package network

import (
	"go.uber.org/zap/zapcore"
	"net"
	"os/exec"
)

const DHCP = "dhcp"
const STATIC = "static"

type NetInterface struct {
	Name    string         `json:"name"`
	Mode    string         `json:"mode"`
	IP      string         `json:"ip"`
	Mask    string         `json:"mask"`
	Gateway string         `json:"gateway"`
	DNS     string         `json:"dns"`
	Ifc     *net.Interface `json:"-"`
}

func (ifc NetInterface) MarshalLogObject(enc zapcore.ObjectEncoder) error {
	enc.AddString("name", ifc.Name)
	enc.AddString("mode", ifc.Mode)
	enc.AddString("ip", ifc.IP)
	enc.AddString("mask", ifc.Mask)
	enc.AddString("gateway", ifc.Gateway)
	enc.AddString("dns", ifc.DNS)
	return nil
}

// RunCmd 执行命令行
func runCmd(cmd ...string) ([]byte, error) {
	command := exec.Command("bash", append([]string{"-c"}, cmd...)...)
	return command.CombinedOutput()
}

type BroadcastInterface struct {
	Name  string
	IP    string
	Mask  string
	BrdIP string
}

// GetBroadcastInterfaces 获取可广播网卡
func GetBroadcastInterfaces() (any, error) {
	ifcs, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	res := make([]BroadcastInterface, 0)
	for i := range ifcs {
		if ifcs[i].Flags&(net.FlagBroadcast|net.FlagUp|net.FlagLoopback|net.FlagRunning) == net.FlagBroadcast|net.FlagRunning|net.FlagUp {
			addrs, _err := ifcs[i].Addrs()
			if _err != nil {
				continue
			}
			for _i := range addrs {
				if ipNet, ok := addrs[_i].(*net.IPNet); ok && ipNet != nil {
					if ip4 := ipNet.IP.To4(); len(ip4) > 0 {
						brd := make([]byte, len(ip4))
						copy(brd, ip4)
						for j := 0; j < len(ipNet.Mask); j++ {
							brd[j] |= ^ipNet.Mask[j]
						}
						res = append(res, BroadcastInterface{
							Name:  ifcs[i].Name,
							IP:    ip4.String(),
							Mask:  net.IPv4(ipNet.Mask[0], ipNet.Mask[1], ipNet.Mask[2], ipNet.Mask[3]).String(),
							BrdIP: net.IPv4(brd[0], brd[1], brd[2], brd[3]).String(),
						})

					}

				}
			}
		}
	}
	return res, nil
}

// EachInterfaces 遍历可用网卡
func EachInterfaces(fn func(ifcName string, ipNet *net.IPNet) bool) {
	ifcs, err := net.Interfaces()
	if err != nil {
		return
	}
	for i := range ifcs {
		if ifcs[i].Flags&(net.FlagBroadcast|net.FlagUp|net.FlagLoopback|net.FlagRunning) == net.FlagBroadcast|net.FlagRunning|net.FlagUp {
			addrs, _err := ifcs[i].Addrs()
			if _err != nil {
				continue
			}
			for _i := range addrs {
				if ipNet, ok := addrs[_i].(*net.IPNet); ok && ipNet != nil {
					if !fn(ifcs[i].Name, ipNet) {
						return
					}
				}
			}
		}
	}
	return
}

// EachIpv4Interfaces 遍历可用ip4网卡
func EachIpv4Interfaces(fn func(ifcName string, ipNet *net.IPNet) bool) {
	EachInterfaces(func(ifcName string, ipNet *net.IPNet) bool {
		if ip4 := ipNet.IP.To4(); len(ip4) > 0 {
			return fn(ifcName, ipNet)
		}
		return true
	})
}
